import socket


def ip_to_int(ip):
    octets = list(map(int, ip.split('.')))
    return sum([octet << (8 * i) for i, octet in enumerate(reversed(octets))])


def int_to_ip(ip_int):
    return '.'.join([str(ip_int >> (8 * i) & 0xFF) for i in reversed(range(4))])


def calculate_broadcast_address(ip, subnet_mask):
    # 将IP地址和子网掩码转换为整数
    ip_int = ip_to_int(ip)
    subnet_mask_int = ip_to_int(subnet_mask)

    # 计算网络地址
    network_address_int = ip_int & subnet_mask_int

    # 计算广播地址
    broadcast_address_int = network_address_int | (
        ~subnet_mask_int & 0xFFFFFFFF)

    # 将广播地址整数转换回点分十进制格式
    broadcast_address = int_to_ip(broadcast_address_int)

    return broadcast_address


def broadcast_udp_msg(lan_ip: str, port: int, mask: str, message: bytes):
    """
    :lan_ip: 局域网ip
    :mask: 子网掩码
    """
    udp_s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  # 创建udp接收data数据
    broadcast_addr = calculate_broadcast_address(lan_ip, mask)
    addr = (broadcast_addr, port)  # 绑定端口号
    # 发起请求
    udp_s.sendto(message, addr)
    udp_s.close()
